#pragma once

#ifndef _BUILDINFUNC_H_
#define _BUILDINFUNC_H_

#include <iostream>
#include "biplTypes.h"
#include <Magick++.h> 

using namespace Magick;

intTypes save(imageTypes& saveImage, const stringTypes& extension){
	stringTypes saveName;
	if(!saveImage.pathname.getStr().empty()){
		saveName = saveImage.pathname + stringTypes("//") + saveImage.filename + stringTypes(".")+ extension;
	}
	else{
		saveName = saveImage.filename + stringTypes(".")+ extension;
	}
	saveImage.getImage()->write(saveName.getStr());
	return intTypes(0);
}

imageTypes open(const std::string fileName){
	imageTypes img(fileName);
	return img;
}

imageTypes compose(imageTypes c, imageTypes dollar){
	c.getImage()->composite(*dollar.getImage(), (unsigned int)dollar.getX(), (unsigned int)dollar.getY(), OverCompositeOp);
	return c;
}

imageTypes canvas(floatTypes x, floatTypes y){
	return imageTypes((unsigned int)x.getVal() ,(unsigned int)y.getVal() , "white");
}

intTypes show(imageTypes img){
	img.show();
	return intTypes(0);
}

intTypes print(const stringTypes& str){
	std::cout << str << '\n';
	return intTypes(0);
}

imageTypes charcoal(imageTypes img, intTypes scale){
	img.getImage()->charcoal((double)(scale.getVal()));
	return img;
}

imageTypes blur(imageTypes img, intTypes radius, floatTypes sigma){
	img.getImage()->blur((double)(radius.getVal()), (double)(sigma.getVal()));
	return img;
}

imageTypes sharpen(imageTypes img, intTypes radius, floatTypes sigma){
	img.getImage()->sharpen((double)(radius.getVal()), (double)(sigma.getVal()));
	return img;
}

imageTypes gray(imageTypes img){
	img.getImage()->type(GrayscaleType);
	return img;
}

imageTypes crop(imageTypes img, pairTypes s_pnt, pairTypes size){
	const Geometry factor( (unsigned int)size.getX(), (unsigned int)size.getY(), (unsigned int)s_pnt.getX(), (unsigned int)s_pnt.getY());
	img.getImage()->crop(factor);
	return img;
}

imageTypes noise(imageTypes img){
	img.getImage()->addNoise(GaussianNoise);
	return img;
}

imageTypes normalize(imageTypes img){
	img.getImage()->normalize();
	return img;
}

imageTypes label(stringTypes& str, stringTypes font_t, intTypes size, floatTypes R, floatTypes G, floatTypes B){
	int canvasSize = str.getStr().size()/2;
	ColorRGB bgcolor(1.0, 1.0, 1.0);
	//bgcolor.alpha(0);
	imageTypes img((unsigned int)size.getVal()*canvasSize, (unsigned int)size.getVal()*canvasSize, bgcolor);
	img.getImage()->transparent(bgcolor);
	// set font color, string, and size
	img.getImage()->fillColor(ColorRGB((double)R.getVal()/255, (double)G.getVal()/255, (double)B.getVal()/255));
	img.getImage()->font(font_t.getStr());
	img.getImage()->fontPointsize((unsigned int)size.getVal());
	img.getImage()->annotate(str.getStr(), CenterGravity);
	return img;
}

imageTypes convolve(imageTypes img, floatTypes value_1, floatTypes value_2, floatTypes value_3,
	                                floatTypes value_4, floatTypes value_5, floatTypes value_6,
									floatTypes value_7, floatTypes value_8, floatTypes value_9)
{
	double kernel[9] = {(double)(value_1.getVal()),(double)(value_2.getVal()),(double)(value_3.getVal()),
						(double)(value_4.getVal()),(double)(value_5.getVal()),(double)(value_6.getVal()),
						(double)(value_7.getVal()),(double)(value_8.getVal()),(double)(value_9.getVal())};
	img.getImage()->convolve(3, kernel);
	return img;

}

#endif